home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Sample Code / Snippets / Development Tools & Languages / DTSCPlusLibrary / Tools / Recipes.C++ < prev   
Encoding:
C/C++ Source or Header  |  1993-01-14  |  31.6 KB  |  2,394 lines  |  [TEXT/MPS ]

  1. #############################################################################
  2. Recipes for MPW C++      1.0
  3. Kent Sandvik DTS        Sunday, June 14, 1992 15:37:54
  4.  
  5. Permission to republish this is granted, as long as the contents
  6. are not modified/altered/shortened in any way without consulting the author first.
  7.  
  8. Place in MPW Folder, and put following line (example) in UserStartup:
  9.     AddMenu    Special 'C++ Recipes/1'    'Open "{MPW}Recipes.C++"'
  10.                                  ^ triggered from option-1
  11.  
  12. Please redirect any comments, bug reports and such to:
  13. ksand@apple.com (Usenet, Internet)
  14. KSAND           (AppleLink)
  15. 75300, 1331     (CompuServe)
  16.  
  17. References:
  18.     C++ Programming Language (second edition), Bjarne Stroustrup
  19.     Annotated C++ Reference Manual, Ellis & Stroustrup
  20.     All kinds of private notes/hacks (Usenet comp.lang.c++, CompuServe)
  21.  
  22. Future plans:
  23.     * more material, bug fixes, better explanations
  24.     * 411 (template/lookup support), or something more hypertext:ish
  25.     
  26. Thanks!
  27.     Johan Strandberg, Common Knowledge
  28.     
  29. #############################################################################
  30.  
  31.  
  32.  
  33.  
  34. // C++ CLASS TEMPLATE
  35. #include <stream.h>
  36.  
  37. class TFoo
  38. {
  39. public:
  40.     TFoo();                                        // constructor
  41.     ~TFoo();                                    // destructor
  42.  
  43. protected:
  44.     long fField;
  45. private:
  46. };
  47.  
  48.  
  49.  
  50.  
  51. // Method implementations
  52. TFoo::TFoo()                                    // constructor
  53. {
  54.     cout << "inside TFoo constructor\n";
  55. }
  56.  
  57.  
  58. TFoo::~TFoo()                                    // destructor
  59. {
  60.     // empty for the moment
  61. }
  62.  
  63.  
  64.  
  65.  
  66. class TBar : public TFoo
  67. {
  68. public:
  69.     TBar()
  70.     {
  71.         cout << "inside TBar constructor\n";
  72.     }
  73.  
  74.  
  75.     virtual void Member();
  76. };
  77.  
  78.  
  79.  
  80. void TBar::Member()
  81. {
  82.     cout << "inside TBar::Member\n";
  83. }
  84.  
  85.  
  86.  
  87.  
  88. TBar* aBar;
  89.  
  90. main()
  91. {
  92.     aBar = new TBar;
  93.     return 0;
  94. }
  95.  
  96.  
  97.  
  98.  
  99. // VOLATILE MACRO
  100. #define VOLATILE(a) ((void) &a)
  101.  
  102.  
  103.  
  104. // GLOBAL SCOPE OPERATOR
  105. int x;
  106.  
  107. void func()
  108. {
  109.     int x = 1;                                    // use local x
  110.     ::x = 2;                                    // use global x
  111. }
  112.  
  113.  
  114.  
  115. // void POINTERS - can be made to point at anything
  116. void* malloc(unsigned size);                    // C style memory allocation
  117. void free(void*);
  118.  
  119. void func()
  120. {
  121.     int* pi = (int*)malloc(10 * sizeof(int));
  122.     char* pc = (char*)malloc(10);
  123.     // ...
  124.     free(pi);
  125.     free(pc);
  126. }
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133. // POINTERS
  134. int* pi;                                        // pointer to int
  135. char** cpp;                                        // pointer to array to char
  136. int(* vp)[10];                                    // pointer to array of 10 ints
  137. int(* fp)(char,
  138.           char*);                                // pointer to function taking 
  139. // (char, char*), returning int
  140.  
  141. char c1 = 'a';                                    // c1 contains 'a'
  142. char* p = &c1;                                    // p contains address of c1
  143. char c2 = *p;                                    // c2 contains 'a'
  144.  
  145. size_t strlen(char* p)
  146. {
  147.     size_t i = 0;
  148.     while (*p++)
  149.         i++;
  150.     return i;
  151. }
  152.  
  153.  
  154.  
  155. // FASTER POINTER STRING COMPARISON - produces better code on most platforms
  156. int strlen(const char* p)
  157. {
  158.     register char* q = p;
  159.     while (*q++)
  160.         return q - p - 1;
  161. }
  162.  
  163.  
  164.  
  165.  
  166. // ARRAYS
  167. float v[3];                                        // array of 3 floats
  168. int a[3][5];                                    // 2-dimensional array of ints (3 times 5)
  169. char* vpc[32];                                    // array of 32 char pointers
  170.  
  171. int v1[1] = {
  172.              1, 2, 3, 4};                        // assigment of array elements
  173.  
  174.  
  175.  
  176. // POINTERS AND ARRAYS
  177. char* p = &alpha[0];                            // make p point at start of alpha array
  178. char* p = alpha;                                // same semantics!
  179.  
  180. extern "C"
  181. int strlen(const char*);
  182. void func()
  183. {
  184.     char v[] = "Jeff Steven"
  185.               char* p = v;
  186.     strlen(p);
  187.     strlen(v);                                    // both gives same value
  188. }
  189.  
  190.  
  191.  
  192.  
  193. // STRUCTURES
  194. struct address
  195. {
  196.     char* name;
  197.     long number;
  198.     char* street;
  199.     char* town;
  200.     char state[2];
  201.     long zip;
  202. };
  203.  
  204.  
  205. address js;
  206. js. name = "Jeff Sandvik";
  207. js. number = 20200;
  208.  
  209.  
  210. address js = {                                    // struct assignment
  211.               "Jeff Sandvik", 20200, "Lucille Ave", "Cupertino", {'C', 'A'}, 95104};
  212.  
  213.  
  214. void printAddress(address p)                    // struct pointer handling
  215. {
  216.     cout << p->name << '\n' << p->number << ' ' 
  217.     << p->street << '\n' << p->town << '\n' 
  218.     << p->state[0] << p->state[1] << ' ' 
  219.     << p->zip << '\n'
  220. }
  221.  
  222.  
  223.  
  224. address current;
  225.  
  226. address setCurrent(address next)                // address handling
  227. {
  228.     address prev = current;
  229.     current = next;
  230.     return prev;
  231. }
  232.  
  233.  
  234. struct link
  235. {                                                // struct self referencing
  236.     link* previous;
  237.     link* next;
  238. };
  239.  
  240.  
  241.  
  242.  
  243.  
  244. // typedef
  245. typedef char* Pchar;
  246. Pchar p1, p2;
  247. char p3 = p1;
  248.  
  249.  
  250. // REFERENCES (&)
  251. int i = 1;                                        // example
  252. int& r = i;
  253. int x = r;                                        // x = 1;
  254. r = 2;                                            // i = 2;
  255.  
  256. void incr(int& a)
  257. {
  258.     a++;
  259. }                                                // function call
  260.  
  261.  
  262. void func()
  263. {
  264.     int x = 1;
  265.     incr(x);                                    // x = 2;
  266. }
  267.  
  268.  
  269.  
  270.  
  271. // const
  272. const int model = 100;
  273. model = 200;                                    // error!
  274.  
  275. const char* pc = "abc";                            // const pc data
  276. pc[3] = 'a';                                    // error!
  277. pc = "def";                                        // ok
  278.  
  279. char* const cp = "abc";                            // constant pointer
  280. cp[3] = 'a';                                    // ok
  281. cp = "def";                                        // error!
  282.  
  283. const char* const pc "abc";                        // data and pointer constant
  284.  
  285. char* strcpy(char* p,
  286.              const char* q);                    // can't modify q
  287.  
  288.  
  289. // ENUMS
  290. enum
  291. {
  292.     kRed, kBlue, kGreen
  293. };                                                // enum list, kRed = 0, kBlue = 1...
  294.  
  295.  
  296. enum
  297. {
  298.     kRed = 200, kBlue, kGreen = 300
  299. };                                                // kBlue = 201
  300.  
  301.  
  302. enum EColors
  303. {
  304.     kRed, kBlue, kGreen
  305. };                                                // named enum
  306.  
  307.  
  308. eColors returnColor();
  309.  
  310. eColors theColor;
  311.  
  312. switch (theColor){
  313.     case kRed:
  314.         // do something
  315.         break;
  316.     case kBlue:
  317.         // do something
  318.         break;
  319.     case kGreen:
  320.         // do something
  321.         break;
  322.     default:
  323.         // do something
  324.         break;
  325. };
  326.  
  327. class foo
  328. {
  329. public:
  330.     enum eColors
  331.     {
  332.         eRed, eBlue, eGreen
  333.     };
  334.     //...
  335.  
  336. };
  337.  
  338.  
  339.  
  340. myClass. fColor = foo::eRed;
  341.  
  342.  
  343. // BITFIELDS
  344. struct ASICReg {
  345.     unsigned enable:     1;        // one bit
  346.     unsigned page:        3;        // three bits
  347.     unsigned :            1;        // unused
  348.     unsigned mode:        2;        // two bits
  349.     unsigned :            4;        // unused
  350.     unsigned access:    1;        // one bit
  351.     unsigned length:    1;
  352.     unsigned non_res:    1;
  353. };
  354.  
  355. ASICReg* SR = (sreg *)0xA800;                    // fictiv address, memory mapped I/O
  356. // ...
  357.  
  358. if (SR->access)                    // true?
  359. {                
  360.     // clean up the state
  361.     SR->access = 0;
  362. }
  363.  
  364.  
  365. // UNIONS
  366. struct entry {
  367. char* name;
  368. char type;                                        // tagged value for union
  369. union
  370. {
  371.     char* stringValue;                            // char string     type = 's'
  372.     int intValue;                                // or int variable type = 'i'
  373. };
  374.  
  375.  
  376. };
  377.  
  378. union foo
  379. {                                                // named union
  380.     int i;
  381.     int* p;
  382. };
  383.  
  384.  
  385.  
  386.  
  387. // MODULO
  388. const int RANGE = 100;
  389. int i;
  390.  
  391. i%= RANGE;                                        // i is in the range 0...RANGE-1
  392.  
  393.  
  394. // BITWISE LEFT SHIFT
  395. int i = 0x8000;
  396. i<<= 1;                                            // left shift one step
  397.  
  398.  
  399. // BITWISE XOR
  400. int i = 0x8000;
  401. i^= 0x3000;                                        // note, no space between ^ and =!!!
  402.  
  403. // BITWISE OR
  404. int i = 0x8000;
  405. i|= 0x3000;
  406.  
  407. // BITWISE AND
  408. int i = 0x8000;
  409. i&= 0x3000;
  410.  
  411.  
  412. // ERROR STREAMS
  413. int numErrors;
  414.  
  415. double error(const char* s)
  416. {
  417.     cerr << "error: " << s << "\n";
  418.     numErrors++;
  419.     return 1;
  420. }
  421.  
  422.  
  423.  
  424.  
  425. // TYPE CONVERSION
  426. int foo = 56;
  427. float bar = float(foo);
  428.  
  429. char* p = (char*)0xA800;                        // typecast of address
  430. typedef char* Address;
  431. Address p = Address(0xA800);                    // same as above
  432.  
  433.  
  434. // free store (new, delete, set_new_handler...)
  435.  
  436. main()                                            // simple example
  437. {
  438.     char* p = saveString("foobar");
  439.     delete[]p;                                    // note new 2.0 delete syntax
  440. }
  441.  
  442.  
  443. char* saveString(const char* p)
  444. {
  445.     char* s = new
  446.              char[strlen(p) + 1];
  447.     strcpy(s, p);
  448.     return s;
  449. }
  450.  
  451.  
  452.  
  453. TFoo* aFoo = new TFoo;                            // create object in the free store (heap on MacOS)
  454.  
  455. #include <stream.h>
  456. #include <new.h>
  457.  
  458. void OutofStore()
  459. {
  460.     cerr << "operator new failed : out of store\n";
  461.     exit(1);
  462. }
  463.  
  464.  
  465. main()
  466. {
  467.     set_new_handler(&OutOfStore);                // give address to handler
  468.     char* p = new
  469.              char[100000000000];
  470.     cout << "what, it works..., address = ",  long(p)<< '\n';
  471.     // new returns 0 if it can't find enough memory - test for NULL
  472. }
  473.  
  474.  
  475.  
  476.  
  477.  
  478. // STACK BASED OBJECTS
  479. void func()
  480. {
  481.     TFoo aFoo;                                    // local -> placed on the stack
  482.     aFoo.Beep();
  483. }                                                // removed from stack automatically
  484.  
  485.  
  486.  
  487.  
  488. // ? : CONDITIONAL EXPRESSION
  489. max = (a <= b) ? b : a;
  490.  
  491.  
  492. // LINKAGE TO NON-C++ CODE - no function name mangling
  493. #ifdef __cplusplus
  494. extern "C"
  495. {
  496. #endif
  497.  
  498.     pascal Handle NewHandle(Size byteCount)
  499. #pragma parameter DisposHandle(__A0)
  500.     pascal void DisposHandle(Handle h) = 0xA023;
  501. #ifdef __cplusplus
  502. }
  503. #endif
  504.  
  505. extern "C"
  506. {
  507.     char* strcpy(char* ,
  508.                  const char*);
  509.     int strcmp(const char* ,
  510.                const char*);
  511.     // ...
  512. }
  513.  
  514.  
  515. extern "C"
  516. {
  517. #include "myCHeaderFiles.h"
  518. }
  519.  
  520.  
  521.  
  522.  
  523. // RECURSION
  524. int fac(int n)
  525. {
  526.     return (n > 1) ? n * fac(n - 1) : 1;
  527. }
  528.  
  529.  
  530.  
  531.  
  532. // OVERLOADED FUNCTION NAMES
  533. void print(int);                                // integer print
  534. void print(const char*);                        // string print
  535.  
  536.  
  537. // DEFAULT FUNCTION ARGUMENTS
  538. void print(int value,
  539.            int base = 10);
  540. //...
  541. print(30);                                        // will use base=10 inside print
  542.  
  543. void foo(int,
  544.          char* ,
  545.          int = 0,
  546.          char*= 0);
  547. // have to define defaults from right!
  548.  
  549.  
  550.  
  551. // UNSPEFIFIED AMOUNT OF FUNCTION ARGUMENT
  552. int printf(const char ...);
  553.  
  554.  
  555. // POINTERS TO FUNCTIONS
  556. void error(char* p)
  557. {
  558.     /* ... */
  559. }
  560.  
  561.  
  562. void(* efunc)(char*);                            // pointer to function
  563.  
  564. void func()
  565. {
  566.     efunc = &error;                                // give address to function ptr
  567.     (*efunc)("mayday");                            // call the function via ptr
  568. }
  569.  
  570.  
  571.  
  572. typedef void(* PF)();
  573.  
  574. PF editOps[] = {                                // edit operations
  575.                 &cut, &paste, ©};
  576.  
  577. PF fileOps[] = {
  578.                 &new, &save, &close};
  579.  
  580. PF MenuEntry = editOps;
  581. //...
  582. (*MenuEntry[3])();                                // selected copy! trigger copy function
  583.  
  584.  
  585. // MACROS
  586. #define print(a,b)   cout << (a) << (b)        // argument usage
  587. #define forever for(;;)
  588. #define MIN(a,b)   (((a)<(b))?(a):(b))
  589.  
  590.  
  591.  
  592. // this POINTER
  593. //always defined as X *const this; where X is the name of the class
  594.  
  595. class X
  596. {
  597.     int m;
  598. public:
  599.     int readm()
  600.     {
  601.         return this->m;
  602.     }                                            // makes things more clear!
  603.  
  604.  
  605.  
  606.  
  607. class dlink
  608. {
  609.     dlink* previous;
  610.     dlink* successor;
  611. public:
  612.     void append(dlink*);
  613.     // ...
  614. };
  615.  
  616.  
  617.  
  618. void dlink::append(dlink* p)
  619. {
  620.     p->successor = successor;
  621.     p->previous = this;
  622.     successor->previous = p;
  623.     successor = p;
  624. }
  625.  
  626.  
  627.  
  628. dlink* listHead;
  629. void func(dlink* a,
  630.           dlink* b)
  631. {
  632.     // ...
  633.     listHead->append(a);
  634.     listHead->append(b);
  635. }
  636.  
  637.  
  638.  
  639.  
  640. // const MEMBER FUNCTIONS
  641. class X
  642. {
  643.     int m;
  644. public:
  645.     readme() const
  646.     {
  647.         return m;
  648.     }                                            // const member function, read-only
  649.  
  650.  
  651.     writeme(int i)
  652.     {
  653.         m = i;
  654.     }
  655.  
  656.  
  657. };
  658.  
  659.  
  660.  
  661. // you are able to change a value through an explicit this cast:
  662. class X
  663. {
  664.     int m;
  665. public:
  666.     // ...
  667.     void implicitCheat() const
  668.     {
  669.         m++;
  670.     }                                            // error!
  671.  
  672.  
  673.     void explicitCheat() const
  674.     {
  675.         ((X *)this)->m++;
  676.     }                                            // ok
  677.  
  678.  
  679. };
  680.  
  681.  
  682.  
  683.  
  684. // const CLASSES
  685. void func(X& mutable,
  686.           const X& constant)
  687. {
  688.     mutable.readme();                            // ok
  689.     mutable.writeme(7);                            // ok
  690.     constant.readme();                            // ok
  691.     constant.writeme(7);                        // error
  692. }
  693.  
  694.  
  695.  
  696.  
  697. // CONSTRUCTORS
  698. class TDate
  699. {
  700.     // ...
  701.     TDate(int day,
  702.           int month,
  703.           long year);                            // constructor
  704.     TDate(int month,
  705.           long year);                            // other form            
  706.     TDate(long);                                // 910915, ANSI standard
  707.     TDate();                                    // default today's date
  708.     TDate(const char*);                            // string "Sun 15 Sept 1991"
  709.     TDate(int d = 0,
  710.           int m = 0,
  711.           long year = 0);                        // default values
  712. };
  713.  
  714.  
  715. TDate today(15,
  716.             9,
  717.             1991);                                // stack based class
  718. TDate tomorrow("Mon 16 Sept 1991");
  719. TDate now;                                        // today's date
  720. TDate d = today;                                // default copy constructor! bitwise copy
  721.  
  722. TDate::TDate(int d,
  723.              int m,
  724.              long y)                            // constructor function declaration
  725. {
  726.     // ...
  727. }
  728.  
  729.  
  730.  
  731.  
  732. // DESTRUCTORS
  733. class TStack
  734. {
  735.     int size;
  736.     char* top;
  737.     char* s;
  738. public:
  739.     TStack(int sz)
  740.     {
  741.         top = s = new
  742.                  char[size = sz];
  743.     }
  744.  
  745.  
  746.     ~TStack()
  747.     {
  748.         delete[]s;
  749.     }                                            // destructor
  750.  
  751.  
  752.     void push(char c)
  753.     {
  754.         *top++ = c;
  755.     }
  756.  
  757.  
  758.     void pop()
  759.     {
  760.         return *--top;
  761.     }
  762.  
  763.  
  764. };
  765.  
  766.  
  767. void func()
  768. {
  769.     TStack s1(100);
  770.     TStack s2(200);
  771.     s1.push('a');
  772.     s2.push('b');
  773.     char ch = s2.pop();
  774.     cout << ch << '\n';
  775. }                                                // automatic call of destructor
  776.  
  777.  
  778.  
  779.  
  780.  
  781. // inline CALLS - (see ARM 102 and TN307 for more info when compiler will not inline
  782. class TFoo
  783. {
  784. public:
  785.     void func1()
  786.     {
  787.         /*...*/
  788.     }                                            // this code is inlined
  789.  
  790.  
  791.     void func2();
  792. };
  793.  
  794.  
  795. inline void TFoo::func2()
  796. {
  797.     // this code is inlined
  798.     // ...
  799. }
  800.  
  801.  
  802.  
  803.  
  804. // friend USE
  805. class x
  806. {
  807.     friend class y;                                // class y has access to x's private parts
  808.     // ...
  809. };
  810.  
  811.  
  812. class x
  813. {
  814.     friend void y::f();                            // y::f() member function has access to
  815.     //...                        // x's private parts
  816. };
  817.  
  818.  
  819.  
  820.  
  821. // CLASS MEMBER NAME QUALIFICATION
  822. class X
  823. {
  824.     int m;
  825. public:
  826.     int getm() const
  827.     {
  828.         return m;
  829.     }
  830.  
  831.  
  832.     void setm(int m)
  833.     {
  834.         X::m = m;
  835.     }                                            // name qualification
  836.  
  837.  
  838. };
  839.  
  840.  
  841. class TFile()
  842. {
  843.     // ...
  844.     int open(const char* ,
  845.              const char*);
  846. }
  847.  
  848.  
  849. ;
  850.  
  851. int TFile::open(const char* name,
  852.                 const char* spec)
  853. {
  854.     // ...
  855.     if (::open(name, flag))
  856.     {
  857.         // stdclib open called
  858.         // ...
  859.     }
  860.     // ...
  861. }
  862.  
  863.  
  864.  
  865.  
  866. // NESTED CLASSES
  867. class TSet
  868. {
  869.     struct setmem
  870.     {
  871.         int mem;
  872.         setmem* next;
  873.         setmem(int m,
  874.                setmem* n)
  875.         {
  876.             mem = m;
  877.             next = n;
  878.         }
  879.  
  880.  
  881.     };
  882.  
  883.  
  884.     setmem* first;                                // nested class struct
  885. public:
  886.     TSet()
  887.     {
  888.         first = NULL;
  889.     }
  890.  
  891.  
  892.     insert()
  893.     {
  894.         first = new setmem(m, first);
  895.     }
  896.     // ...
  897.  
  898. };
  899.  
  900.  
  901.  
  902.     
  903. // nicer with friends:
  904. class TSetmem
  905. {
  906.     friend class TSet;                            // access to members of TSet only
  907.     int mem;
  908.     setmem* next;
  909.     setmem(int m,
  910.            setmem* n)
  911.     {
  912.         mem = m,  next = n;
  913.     }
  914.     // other useful members
  915.  
  916. };
  917.  
  918.  
  919. class TSet
  920. {
  921.     setmem* first;
  922. public:
  923.     TSet()
  924.     {
  925.         first = NULL;
  926.     }
  927.  
  928.  
  929.     insert(int m)
  930.     {
  931.         first = new setmem(m, first);
  932.     }
  933.     // ...
  934.  
  935. };
  936.  
  937.  
  938. class X
  939. {                                                // name scoping 
  940. private:
  941.     struct M1
  942.     {
  943.         int m;
  944.     }
  945.     public:
  946.     struct M2
  947.     {
  948.         int m;
  949.     } M1 f(M2);                                    // member function
  950. };
  951.  
  952.  
  953. void func()
  954. {
  955.     M1 a;                                        // error, 'M1' not in scope
  956.     M2 b;                                        // ok
  957.     X::M1 c;                                    // error, 'M1' private
  958.     X::M2 d;                                    // ok
  959. }
  960.  
  961.  
  962.  
  963.  
  964. // static CLASS MEMBERS
  965. class TTask
  966. {
  967. public:
  968.     // ...
  969.     static TTask* chain;                        // static field, one copy of the TTask only
  970.     static void Schedule();                        // static member function
  971.     // ...
  972. };
  973.  
  974.  
  975.  
  976. TTask* TTask::chain = NULL;
  977. void TTask::Schedule()
  978. {
  979.     /* ....*/
  980. }
  981.  
  982.  
  983. ;
  984.  
  985. ....
  986. if(TTask::chain == NULL)                        // must be qualified by class name
  987. {    
  988.     // do something
  989. }
  990.  
  991. TTask::Schedule();                                // call the static member function
  992.  
  993.  
  994. // POINTERS TO MEMBER FUNCTIONS
  995. typedef long(TFoo::* Function)();
  996. enum eGenerator
  997. {
  998.     SIMPLE, PRACTICAL, COMPLEX
  999. };
  1000.  
  1001.  
  1002.  
  1003. class TFoo
  1004. {
  1005. private:
  1006.     Function fGenerator;                        // pointer to Generate function
  1007.     int fVal;
  1008. public:
  1009.     TFoo(eGenerator);
  1010.     long Simple()
  1011.     {
  1012.         return 2;
  1013.     }
  1014.  
  1015.  
  1016.     long Practical()
  1017.     {
  1018.         return 4;
  1019.     }
  1020.  
  1021.  
  1022.     ;
  1023.     long Complex()
  1024.     {
  1025.         return 6;
  1026.     }
  1027.  
  1028.  
  1029.     long Generate()
  1030.     {
  1031.         return this->*fGenerator();
  1032.     }                                            // use the function fGenerator is pointing at
  1033.  
  1034.  
  1035. };
  1036.  
  1037.  
  1038.  
  1039. TFoo::TFoo(eGenerator theGenerator)
  1040. {
  1041.     switch(theGenerator)                        // set pointer to defined function
  1042.     {
  1043.         case SIMPLE:
  1044.             this->fGenerator = &TFoo:Simple;
  1045.             break;
  1046.         case PRACTICAL:
  1047.             this->fGenerator = &TFoo::Practical;
  1048.             break;
  1049.         case COMPLEX:
  1050.             this->fGenerator = &TFoo:Complex;
  1051.     }
  1052. }
  1053.  
  1054.  
  1055.  
  1056.  
  1057.  
  1058. // CLASS OBJECTS AS MEMBERS
  1059. class TClassDef
  1060. {
  1061.     table members;
  1062.     int numMembers;
  1063.     // ...
  1064.     TClassDef(int size);
  1065.     ~TClassDef();
  1066. };
  1067.  
  1068.  
  1069.  
  1070. TClassDef::TClassDef(int size) :
  1071.     members(size)                                // pass information for init
  1072. {
  1073.     numMembers = size;
  1074.     // ...
  1075. }
  1076.  
  1077.  
  1078. // ARRAYS OF CLASS OBJECTS
  1079. TTable tbl[10];                                    // will generate an array of 10 TTable objects
  1080.  
  1081.  
  1082. // new/delete OPERATOR OVERLOADING
  1083. class TName
  1084. {
  1085. public:
  1086.     char* string;
  1087.     TName* next;
  1088.     double value;
  1089.  
  1090.     TName(char* ,
  1091.           double name*);
  1092.     ~TName();
  1093.  
  1094.     void* operatornew(size_t);
  1095.     void operatordelete(void* ,
  1096.                         size_t);
  1097. private:
  1098.     enum
  1099.     {
  1100.         N_ALL = 128
  1101.     };
  1102.  
  1103.  
  1104.     static name* nfree;
  1105. };
  1106.  
  1107.  
  1108.  
  1109. void* TName::operatornew(size_t)
  1110. {
  1111.     register TName* p = nfree;                    // first allocate
  1112.  
  1113.     if (p)
  1114.         nfree = p->next;
  1115.     else
  1116.     {
  1117.         TName * q = (TName *)new
  1118.                    char[N_ALL * sizeof(name)];
  1119.         for (p = nfree = &q[N_ALL - 1]; q < p; p--)
  1120.             p->next = p - 1;
  1121.         p->next = NULL;
  1122.     }
  1123.     return p;
  1124. }
  1125.  
  1126.  
  1127.  
  1128. void TName::operatordelete(void* p,
  1129.                            size_t)
  1130. {
  1131.     ((TName *)p)->next = nfree;
  1132.     nfree = (TName *)p;
  1133. }
  1134.  
  1135. //....
  1136. * TName::nfree = 0;                                // explicit initialization of the value
  1137.     
  1138.  
  1139.  
  1140. // DERIVED CLASSES
  1141. class TEmployee
  1142. {
  1143. private:
  1144.     char* name;
  1145.     short age;
  1146.     short department;
  1147. public:
  1148.     TEmployee();
  1149.     print() const
  1150.     {
  1151.         /*...*/
  1152.     }
  1153.  
  1154.  
  1155.     TEmployee* next;
  1156. }
  1157.  
  1158. class TManager : public TEmployee
  1159. {
  1160.     TEmployee* group;
  1161.     short level;
  1162. public:
  1163.     TManager();
  1164.     print() const
  1165.     {
  1166.         /*...*/
  1167.     }
  1168.  
  1169.  
  1170. };
  1171.  
  1172.  
  1173. void TEmployee::print()
  1174. {
  1175.     cout << "Employee information...\n";
  1176. }
  1177.  
  1178.  
  1179. void TManager::print()
  1180. {
  1181.     TEmployee::print();                            // print employee information
  1182.     cout << "Manager information...\n";
  1183. }
  1184.  
  1185.  
  1186. void func()
  1187. {
  1188.     TManager m1,  m2;
  1189.     TEmployee e1,  e2;
  1190.     TEmployee * elist;
  1191.  
  1192.     elist = &m1;                                // put m1 on elist
  1193.     m1.next = &e2;                                // put e1 on elist
  1194.     e1.next = &m2;
  1195.     m2.next = &e2;
  1196.     e2.next = NULL;                                // last in the elist
  1197. }
  1198.  
  1199.  
  1200.     void g()
  1201.     {
  1202.         TManager MM;
  1203.         Temployee * pe = &MM;                    // ok
  1204.  
  1205.         TEmployee ee;
  1206.         manager * PM = ⅇ                        // error, not every TEmployee is a TManager
  1207.  
  1208.         PM->level = 2;                            // won't work, no space for level
  1209.  
  1210.         PM = (TManager *)pe;                    // ok
  1211.         PM->level = 2;                            // ok
  1212.     }
  1213.  
  1214.  
  1215.  
  1216.  
  1217. // DERIVED CONSTRUCTORS & DESTRUCTORS
  1218. // class objects are constructed from the bottom up, first the base,
  1219. // then the members, then the derived class itself. They are destroyed
  1220. // in the opposite order
  1221.  
  1222. class TEmployee
  1223. {
  1224.     // ...
  1225. public:
  1226.     TEmployee(char* n,
  1227.               int d);
  1228. };
  1229.  
  1230.  
  1231. class TManager:: public TEmployee
  1232. {
  1233.     // ....
  1234. public:TManager(char* n, int l, int d);
  1235. }
  1236.  
  1237.  
  1238. ;
  1239.  
  1240. TEmployee::TEmployee(char* n,
  1241.                      int d) :
  1242.     name(n),
  1243.     department(d)
  1244. {
  1245.     next = list;
  1246.     list = this;
  1247. }
  1248.  
  1249. TManager::TManager(char* n,
  1250.                    int l,
  1251.                    int d) :
  1252.     TEmployee(n, d),
  1253.     level(l),
  1254.     group(0)
  1255. {
  1256.     //...
  1257. }
  1258.  
  1259.  
  1260. // CLASS HIERARCHIES
  1261. class TEmployee { /* .... */ };
  1262. class TManager: public TEmployee {/* .... */};
  1263. class TDirector: public TManager {'* .... */};
  1264. class TTemporary {/* ....*/};
  1265.  
  1266.  
  1267. // MULTIPLE INHERITANCE
  1268. class TConsultant: public TManager, public TTemporary {/* .... */};
  1269.  
  1270. class TTask
  1271. {
  1272.     //
  1273.     virtual info* debug();
  1274. };
  1275.  
  1276.  
  1277.  
  1278. class TDisplayed
  1279. {
  1280.     // ...
  1281.     virtual info* debug();
  1282. };
  1283.  
  1284.  
  1285.  
  1286.  
  1287. class TSatellite : public TTask, public TDisplayed
  1288. {
  1289.     // ...
  1290. };
  1291.  
  1292.  
  1293.  
  1294. void func(TSatellite& s)                        // ambiguity with member function names
  1295. {
  1296.     s.draw();                                    // TDisplayed::draw()
  1297.     s.delay(10);                                // TTask::delay(int x);
  1298.     s.xmit();                                    // TSatellite::Xmit()
  1299.  
  1300.     info * d_info = s.debug;                    // ambiguity problems!
  1301.     d_info = s.TTask::debug();                    // ok
  1302.     d_info = s.TDisplayed::debug()                // ok
  1303.  
  1304.             // with pointers, TSatellite *s
  1305.             d_info = s->TTask::debug();
  1306.     d_info = s->TDisplayed::debug();
  1307. }
  1308.  
  1309.  
  1310.  
  1311. // better to define new member functions inside TSatellite!
  1312. class TSatellite : public TTask, public TDisplayed
  1313. {
  1314.     // ...
  1315.  
  1316.     info* satelliteDebug()
  1317.     {
  1318.         info * d1 = TTask::debug();
  1319.         info * d2 = TDisplayed::debug();
  1320.         return d1.merge(d2);
  1321.     }
  1322.  
  1323.  
  1324. };
  1325.  
  1326.  
  1327.  
  1328.  
  1329. // VIRTUAL FUNCTIONS
  1330. class TEmployee
  1331. {
  1332.     char* name;
  1333.     short department;
  1334.     // ...
  1335.     TEmployee* next;
  1336.     static TEmployee* list;
  1337. public:
  1338.     TEmployee(char* n,
  1339.               int d);
  1340.     // ..
  1341.     static void printList();
  1342.     virtual void print() const;                    // virtual function, can be
  1343. };                                                // overridden
  1344.  
  1345.  
  1346.  
  1347. ....
  1348. void TEmployee::print() const
  1349. {
  1350.     cout << name << '\t' << department << '\n';
  1351.     // ...
  1352. }
  1353.  
  1354.  
  1355.  
  1356. class TManager:: public TEmployee
  1357. {
  1358.     TEmployee * group;
  1359.     short level;
  1360.     // ...
  1361. public:TManager(char* n, int l, int d);
  1362.     // ...
  1363.     void print const();                            // we could override this - virtual
  1364. }
  1365.  
  1366.  
  1367. ;
  1368.  
  1369. ....
  1370. void TManager::print() const
  1371. {
  1372.     cout << level << '\n';
  1373.     //...
  1374. }
  1375.  
  1376.  
  1377.  
  1378.  
  1379. // ABSTRACT CLASSES - PURE VIRTUAL FUNCTIONS
  1380. class TShape
  1381. {                                                // has pure virtual function = abstract class
  1382.     // ...
  1383. public:
  1384.     virtual void rotate(int x) = 0;                // pure virtual function
  1385. };
  1386.  
  1387.  
  1388. class TMyShape
  1389. {
  1390.     // ...
  1391. public:
  1392.     virtual void rotate(int x)
  1393.     {
  1394.         /* ... */
  1395.     }                                            // have to create this member function
  1396.  
  1397.  
  1398. };
  1399.  
  1400.  
  1401.  
  1402. ...
  1403. TShape aShape;                                    // error!
  1404. TMyShape anotherShape;                            // ok
  1405.  
  1406.  
  1407. // virtual base classes
  1408.  
  1409. class TWindow
  1410. {
  1411.     // window information
  1412.     void _Draw();                                // internal window draw
  1413.     virtual void Draw()
  1414.     {
  1415.         _Draw();
  1416.     }                                            // calls by default _Draw()
  1417.  
  1418.  
  1419. };
  1420.  
  1421.  
  1422.  
  1423. class TWindowBorder : public virtual TWindow
  1424. {
  1425.     // border information
  1426.     void _Draw();                                // draw border
  1427.     void Draw();
  1428. };
  1429.  
  1430.  
  1431.  
  1432. class TWindowMenu : public virtual TWindow
  1433. {
  1434.     // menu information
  1435.     void _Draw();                                // draw menu
  1436.     void Draw();
  1437. };
  1438.  
  1439.  
  1440. class TWindowBorderMenu : public virtual TWindow, public TWindowBorder, public TWindowMenu
  1441. {
  1442.     // ...
  1443.     void _Draw();                                // draw specific stuff
  1444.     void Draw();
  1445. };
  1446.  
  1447.  
  1448.  
  1449. // every class defined virtual base class will be represented by a *single*
  1450. // object of that class.
  1451. void TWindowBorder::Draw()
  1452. {
  1453.     TWindow::Draw();
  1454.     _Draw();                                    // draw the border
  1455. }
  1456.  
  1457.  
  1458. void TWindowMenu::Draw()
  1459. {
  1460.     TWindow::Draw();
  1461.     _Draw();                                    // draw the menu
  1462. }
  1463.  
  1464.  
  1465. void TWindowBorderMenu::Draw()
  1466. {
  1467.     TWindow::Draw();
  1468.     TWindowBorder::Draw();
  1469.     TWindowMenu::Draw();
  1470.     _Draw();                                    // draw specific stuff
  1471. }
  1472.  
  1473.  
  1474.  
  1475.  
  1476. // ACCESS CONTROL
  1477. // private (class only), protected (shareable by inheritance),
  1478. // public (open)
  1479. class X
  1480. {
  1481. private:                                        // no definition = private
  1482.     enum
  1483.     {
  1484.         A, B
  1485.     };
  1486.  
  1487.  
  1488.     void f(int x);
  1489.     int a;
  1490. };
  1491.  
  1492.  
  1493. void X::f(int x)
  1494. {
  1495.     if (x < A)
  1496.         f(x + B);
  1497.     a++;
  1498. }
  1499.  
  1500.  
  1501. void g(X& x)
  1502. {
  1503.     int i = X::A;                                // error, X::A is private
  1504.     x.f(2);                                        // error, X::f() is private
  1505.     x.a++;                                        // error X::a is private
  1506. }
  1507.  
  1508.  
  1509. // PROTECTED MEMBERS
  1510. class X
  1511. {
  1512.     // private by default
  1513.     int priv;
  1514. protected:
  1515.     int prot;
  1516. public:
  1517.     int publ;
  1518.     void m();
  1519. };
  1520.  
  1521.  
  1522. void X::m()
  1523. {
  1524.     priv = 1;                                    // ok
  1525.     prot = 2;                                    // ok
  1526.     publ = 3;                                    // ok
  1527. }
  1528.  
  1529.  
  1530. class Y : public X
  1531. {
  1532.     void mDerived();
  1533. };
  1534.  
  1535.  
  1536. void Y::mDerived()
  1537. {
  1538.     priv = 1;                                    // error, priv is private inside X
  1539.     prot = 2;                                    // ok, inherited
  1540.     publ = 3;                                    // ok, public class
  1541. }
  1542.  
  1543.  
  1544. void f(Y* p)
  1545. {
  1546.     p->priv = 1;                                // error, priv is private
  1547.     p->prot = 2;                                // error, prot is protected, and no inheritance
  1548.     p->publ = 3;                                // ok, public class
  1549. }
  1550.  
  1551.  
  1552.  
  1553.  
  1554. // ACCESS TO BASE CLASS
  1555. class X
  1556. {
  1557. public:
  1558.     int a;
  1559.     // ...
  1560. };
  1561.  
  1562.  
  1563. class Y1 : public X
  1564. {                                                /*...*/
  1565. } class Y2 : protected X
  1566. {                                                /* ... */
  1567. } class Y3 : private X
  1568. {                                                /* ... */
  1569. }                                                // private default
  1570.  
  1571. void f(Y1* p1,
  1572.        Y2* p2,
  1573.        Y3* p3)
  1574. {
  1575.     X * q1 = p1;                                // ok, X is a public base class of Y1
  1576.     p1->a = 7;                                    // ok, internal reference to private field
  1577.     q1 = p2;                                    // error, X is a protected base of Y2
  1578.     p2->a = 7;                                    // error, 
  1579.     q1 = p3;                                    // error, X is a private base of Y3
  1580.     p3->a = 7;                                    // error
  1581. }
  1582.  
  1583.  
  1584.  
  1585.  
  1586. // VIRTUAL DESTRUCTORS
  1587. class TFoo
  1588. {
  1589. public:
  1590.     TFoo();                                        // constructor
  1591.     virtual~ TFoo();                            // virtual destructor 
  1592.     // ...
  1593. };
  1594.  
  1595.  
  1596.  
  1597. // this makes it possible for the compiler to keep track of each destructor
  1598. // and the ordering. Most destructors should be virtual!
  1599.  
  1600.  
  1601.  
  1602. // new - PLACEMENT OPERATOR
  1603. class X
  1604. {
  1605.     // ...
  1606. public:
  1607.     X(int);
  1608. };
  1609.  
  1610.  
  1611.  
  1612. void* operatornew(size_t,
  1613.                   void* p)
  1614. {
  1615.     return p;
  1616. }
  1617.  
  1618.  
  1619.  
  1620. char buffer[sizeof(X)];
  1621.  
  1622. void f(int i)
  1623. {
  1624.     X * p = new(buffer)X(i);                    // place X in buffer!
  1625.     // ...
  1626. }
  1627.  
  1628.  
  1629.  
  1630. class TArena
  1631. {
  1632.     // ...
  1633.     virtual void* alloc(size_t) = 0;
  1634.     virtual void free(void) = 0;
  1635. };
  1636.  
  1637.  
  1638. void* operatornew(size_t,
  1639.                   sz,
  1640.                   Arena* a)
  1641. {
  1642.     return a.alloc(size);
  1643. }
  1644.  
  1645.  
  1646. ...
  1647. extern Arena* Persistent;
  1648. extern Arena* Shared;
  1649.  
  1650. void g(int i)
  1651. {
  1652.     X * p = new(Persistent)X(i);                // X in persistent storage
  1653.     X * q = new(Shared)X(i);                    // X in shared memory
  1654.     // ...
  1655. }
  1656.  
  1657.  
  1658.  
  1659.  
  1660. void h(X* p)
  1661. {
  1662.     p->~X();                                    // call destructor
  1663.     Persistent->free(p);                        // free actual memory
  1664. }
  1665.  
  1666.  
  1667.  
  1668.  
  1669. // OPERATOR OVERLOADING
  1670. class TComplex
  1671. {                                                // class definition
  1672.     double re, im;
  1673. public:
  1674.     TComplex(double r,
  1675.              double i = 0)
  1676.     {
  1677.         re = r,  im = i;
  1678.     }
  1679.  
  1680.  
  1681.     friend complex operator+(TComplex,
  1682.                              TComplex);
  1683.     friend complex operator*(TComplex,
  1684.                              TComplex);
  1685.  
  1686.     TComplex& operator+=(TComplex);
  1687.     TComplex& operator-=(TComplex);
  1688. };
  1689.  
  1690.  
  1691.  
  1692. inline TComplex& TComplex::operator+=(TComplex a)
  1693. {
  1694.     re += a.re;
  1695.     im += a.im;
  1696.     return this;
  1697. }
  1698.  
  1699.  
  1700. inline TComplex operator+(TComplex a,
  1701.                           TComplex b)
  1702. {
  1703.     return TComplex(a.re + b.re, a.im + b.im);
  1704. }
  1705.  
  1706.  
  1707.  
  1708.  
  1709. void f()                                        // usage
  1710. {
  1711.     complex a = complex(1, 3.1);
  1712.     complex b = complex(1.2, 2);
  1713.     complex c = b;
  1714.  
  1715.     a = b + c;
  1716.     b = b + c * a;
  1717.     c = a * b + complex(1, 2);
  1718.  
  1719.     complex d = operator+(a, b);                // explicit call
  1720.     complex e = 23;                                // takes default i value
  1721. }
  1722.  
  1723.  
  1724.  
  1725.  
  1726. // CONVERSION OPERATORS
  1727. class TTiny
  1728. {
  1729.     char v;
  1730.     void assign(int i)
  1731.     {
  1732.         if (i > 63)
  1733.         {
  1734.             error("range error");
  1735.             v = i &~63;
  1736.         }
  1737.         v = i;
  1738.     }
  1739.  
  1740.  
  1741. public:
  1742.     TTiny(int i)
  1743.     {
  1744.         assign(i);
  1745.     }
  1746.  
  1747.  
  1748.     TTiny(const TTiny& t)
  1749.     {
  1750.         v = t.v;
  1751.     }
  1752.  
  1753.  
  1754.     TTiny& operator=(const TTiny& t)
  1755.     {
  1756.         v = t.v;
  1757.         return *this;
  1758.     }
  1759.  
  1760.  
  1761.     TTiny& operator=(int i)
  1762.     {
  1763.         assign(i);
  1764.         return *this;
  1765.     }
  1766.  
  1767.  
  1768.     operator int()
  1769.     {
  1770.         return v;
  1771.     }                                            // conversion operator!
  1772.  
  1773.  
  1774. };
  1775.  
  1776.  
  1777. void main()
  1778. {
  1779.     TTiny c1 = 2;
  1780.     TTiny c2 = 62;
  1781.     TTiny c3 = c2 - c1;                            // c3 = 60
  1782.     TTiny c4 = c3;                                // no range check, not necessary
  1783.     int i = c1 + c2;                            // i = 64
  1784.     c1 = c2 + 2 * c1;                            // c1 = 2
  1785.     c2 = c1 - i;                                // c2 = 2
  1786.     c3 = c2;                                    // no range check, not necessary
  1787. }
  1788.  
  1789.  
  1790.  
  1791.  
  1792. // COPY CONSTRUCTORS
  1793. class TString
  1794. {
  1795.     char* p;
  1796.     int size;                                    // of vector pointed to by p
  1797.  
  1798.     TString(int sz)
  1799.     {
  1800.         p = new
  1801.            char[size = sz];
  1802.     }
  1803.  
  1804.  
  1805.     ~TString()
  1806.     {
  1807.         delete[]p;
  1808.     }
  1809.  
  1810.  
  1811.     TString& operator=(const TString&);
  1812.     TString(const TString&);                    // copy constructor!
  1813. };
  1814.  
  1815.  
  1816.  
  1817. TString::TString(const TString& a)                // (if not defined, bitwise copy generated by compiler
  1818. {
  1819.     p = new
  1820.        char[size = a.size];
  1821.     strcpy(p, a.p);
  1822. }
  1823.  
  1824.  
  1825. TString& TString::operator=(const TString& a)
  1826. {
  1827.     if (this != &a)
  1828.     {
  1829.         delete[]p;
  1830.         p = new
  1831.            char[size = a.size];
  1832.         strcpy(p, a.p);
  1833.     }
  1834.     return *this;
  1835. }
  1836.  
  1837.  
  1838. void f()
  1839. {
  1840.     TString s1(10);
  1841.     TString s2 = s1;                            // initialization, not assignment
  1842. }
  1843.  
  1844.  
  1845.  
  1846. // MEMBERVISE INITIALIZATION
  1847. class TString
  1848. {
  1849. public:
  1850.     TString(const TString& s)
  1851.     //
  1852. private:
  1853.     short len;
  1854.     char str[255];
  1855. };
  1856.  
  1857.  
  1858. TString(const TString&)
  1859. {
  1860.     this->len = s.len;
  1861.     this->str = s.str;
  1862. }
  1863.  
  1864. //...
  1865. TString foo = bar;
  1866.  
  1867.  
  1868. // subscripting  - operator [] overload
  1869.  
  1870. #include <string.h>
  1871.  
  1872. class TAssoc
  1873. {
  1874.     struct pair
  1875.     {
  1876.         char* name;
  1877.         int val;
  1878.     };
  1879.  
  1880.  
  1881.     pair* vector;
  1882.     int max;
  1883.     int nfree;
  1884.  
  1885.     TAssoc(const& TAssoc&);                        // prevent copying
  1886.     TAssoc& operator=(const TAssoc&);            // prevent assignment
  1887. public:
  1888.     TAssoc(int);
  1889.     int& operator[](const char*);                // operator [] overload
  1890.     void PrintAll();
  1891. };
  1892.  
  1893.  
  1894. TAssoc::TAssoc(int s)
  1895. {
  1896.     max = (s < 16) ? s : 16;
  1897.     nfree = 0;
  1898.     vector = new pair[max];
  1899. }
  1900.  
  1901.  
  1902.  
  1903. int& TAssoc::operator[](const char* p)
  1904. // maintain a set of pairs, search for p, return a reference to the
  1905. // integer part of its "pair",, make a new "pair" if "p" has not been seen
  1906.  
  1907.     register pair* pp;
  1908.     
  1909.     for(pp = vector + free - 1 ; vector <= pp; pp--)
  1910.         if( strcmp(p,pp->name) == 0 ) return pp->val;
  1911.     
  1912.     if(nfree == max){        // overflow, grow the vector
  1913.         pair* newvec = new pair[max*2];
  1914.         for(int i=0; i < max; i++)
  1915.             newvec[i] = vector[i];
  1916.         delete [] vector;
  1917.         vector = newvector;
  1918.         max = 2*max;
  1919.     }
  1920.     
  1921.     pp = &vector[nfree++];
  1922.     pp->name = new char[strlen(p) + 1];
  1923.     strcpy(pp->name, p);
  1924.     pp->val = 0;            // initial value
  1925.     return pp->val;
  1926. }
  1927.  
  1928. void TAssoc::PrintAll()
  1929. {
  1930.     for (int i = 0; i < nfree; i++)
  1931.         cout << vector[i].name << ": " << vector[i].val << "\n";
  1932. }
  1933.  
  1934.  
  1935.  
  1936. main()
  1937. {
  1938.     const MAX = 256;
  1939.     char buf[MAX];
  1940.  
  1941.     TAssoc aVector(512);
  1942.     while (cin >> buf)
  1943.         aVector[buf]++;
  1944.     aVector.PrintAll();
  1945. }
  1946.  
  1947.  
  1948.  
  1949.  
  1950.  
  1951. // FUNCTION CALL OVERLOAD
  1952. class TAssoc
  1953. {
  1954.     friend class TAssocIterator;
  1955.     pair* vec;
  1956.     int max;
  1957.     int free;
  1958. public:
  1959.     TAssoc(int);
  1960.     int& operator[](const char*);
  1961. };
  1962.  
  1963.  
  1964.  
  1965. class TAssocIterator
  1966. {
  1967.     TAssoc* cs;                                    // current TAssoc array
  1968.     int i;                                        // current index
  1969. public:
  1970.     TAssocIterator(const TAssoc& s)
  1971.     {
  1972.         cs = &s;
  1973.         i = 0;
  1974.     }
  1975.  
  1976.  
  1977.     pair* operator()()                            // function call operator overload
  1978.     {
  1979.         return (i < cs->free) ? &cs->vec[i++] : NULL;
  1980.     }
  1981.  
  1982.  
  1983. };
  1984.  
  1985.  
  1986.  
  1987. main()                                            // count the occurrences of each word on input
  1988. {
  1989.     const MAX = 256;
  1990.     char buf[MAX];
  1991.     TAssoc aVector(256);
  1992.  
  1993.     while (cin >> buf)
  1994.         aVector[buf]++;
  1995.     TAssocIterator next(aVector);
  1996.     pair * p;
  1997.  
  1998.     while (p = next())
  1999.         cout << p->name << ": " << p->val << '\n';
  2000. }
  2001.  
  2002.  
  2003.  
  2004.  
  2005. // DEREFERENCING OPERATOR (->)
  2006. class TPtr
  2007. {
  2008.     // ...
  2009.     X* operator->();                            // class X
  2010. };
  2011.  
  2012.  
  2013. void f(TPtr p)                                    // usage
  2014. {
  2015.     p->m = 7;                                    // (p.operator->())->m =  7;
  2016. }
  2017.  
  2018.  
  2019.  
  2020. // SMART POINTERS
  2021. class TRecPtr
  2022. {
  2023.     Rec* inCoreAddress;
  2024.     const char* ID;
  2025.     // ...
  2026. public:
  2027.     TRecPtr(const char* p) :
  2028.         identifier(p)
  2029.     {
  2030.         inCoreAddress = NULL;
  2031.     }
  2032.     ~TRecPtr()
  2033.     {
  2034.         WriteToDisk(inCoreAddress, ID);
  2035.     }
  2036.  
  2037.  
  2038.     Rec* operator->();
  2039. };
  2040.  
  2041.  
  2042.  
  2043. Rec* TRecPtr::operator->()
  2044. {
  2045.     if (inCoreAddress == NULL)
  2046.         inCoreAddress = ReadFromDisk(ID);
  2047.     return inCoreAddress;
  2048. }
  2049.  
  2050.  
  2051. main(int argc,
  2052.      const char* argv)                            // usage
  2053. {
  2054.     for (int i = argc; i; i--)
  2055.     {
  2056.         TRecPtr p(argv[i]);
  2057.         p->update();
  2058.     }
  2059. }
  2060.  
  2061.  
  2062.  
  2063.  
  2064. // INCREMENT/DECREMENT OPERATOR OVERLOADING
  2065. class TCheckedPtrToT
  2066. {
  2067.     T* p;
  2068.     T* array;
  2069.     int size;
  2070. public:
  2071.     // bind to array 'a' of size 's' initial value 'p'
  2072.     TCheckedPtrToT(T* p,
  2073.                    T* a,
  2074.                    int s);
  2075.  
  2076.     // bind to single objec initial value 'p'
  2077.     TCheckedPtrToT(T* p);
  2078.  
  2079.     T* operator++();                            // prefix
  2080.     T* operator++(int);                            // postfix - works from Cfront 3.0 forward
  2081.  
  2082.     T* operator--();                            // prefix
  2083.     T* operator--(int);                            // postfix - works from Cfront 3.0 forward
  2084.  
  2085.     T& operator*();                                // prefix
  2086. };
  2087.  
  2088.  
  2089.  
  2090. void func(T a)                                    // example of use
  2091. {
  2092.     T v[200];
  2093.     TCheckedPtrToT p(&v[0], v, 200);            // create object
  2094.     p.operator--(1);
  2095.     p.operator*() = a;                            // runtime error, 'p' out of range
  2096.     p.operator++();
  2097.     p.operator*() = a;                            // ok
  2098. }
  2099.  
  2100.  
  2101.  
  2102.  
  2103. // STRING CLASS IMPLEMENTATION
  2104. #include <iostream.h>
  2105. #include <string.h>
  2106.  
  2107. class TString
  2108. {
  2109.     struct srep
  2110.     {
  2111.         char* s;                                // pointer to data
  2112.         int n;                                    // reference count
  2113.         srep()
  2114.         {
  2115.             n = 1;
  2116.         }
  2117.  
  2118.  
  2119.     };
  2120.  
  2121.  
  2122.     srep* p;
  2123.  
  2124. public:
  2125.     TString(const char*);                        // TString x = "abc";
  2126.     TString();                                    // TString x;
  2127.     TString(const TString&);                    // TString x = TString ...
  2128.     TString& operator=(const char*);
  2129.     TString& operator=(const TString&);
  2130.     ~TString();
  2131.     char& operator[](int i);
  2132.  
  2133.     friend ostream& operator<<(ostream& ,
  2134.                                const TString&);
  2135.     friend istream& operator>>(istream& ,
  2136.                                TString&);
  2137.  
  2138.     friend int operator==(const TString& x,
  2139.                           const char* s)
  2140.     {
  2141.         return strcmp(x.p->s, s) == 0;
  2142.     }
  2143.  
  2144.  
  2145.     friend int operator==(const TString& x,
  2146.                           const TString& y)
  2147.     {
  2148.         return strcmp(x.p->s, y.p->s) == 0;
  2149.     }
  2150.  
  2151.  
  2152.     friend int operator!=(const TString& x,
  2153.                           const char* s)
  2154.     {
  2155.         return strcmp(x.p->s, s) != 0;
  2156.     }
  2157.  
  2158.  
  2159.     friend int operator!=(const TString& x,
  2160.                           const Tstring& y)
  2161.     {
  2162.         return strcmp(x.p->s, y.p->s) != 0;
  2163.     }
  2164.  
  2165.  
  2166. };
  2167.  
  2168.  
  2169.  
  2170. TString::TString()                                // constructor
  2171. {
  2172.     p = new srep;
  2173.     p->s = NULL;
  2174. }
  2175.  
  2176.  
  2177. TString::TString(const TString& x)                // copy constructor
  2178. {
  2179.     x.p->n++;
  2180.     p = x.p;
  2181. }
  2182.  
  2183.  
  2184. TString::TString(const char* s)
  2185. {
  2186.     p = new srep;
  2187.     p->s = new
  2188.           char[strlen(s) + 1];
  2189.     strcpy(p->s, s);
  2190. }
  2191.  
  2192.  
  2193.  
  2194. TString::~TString()
  2195. {
  2196.     if (--p->n == 0)
  2197.     {
  2198.         delete[]p->s;
  2199.         delete p;
  2200.     }
  2201. }
  2202.  
  2203.  
  2204.  
  2205.  
  2206. TString& TString::operator=(const char* s)
  2207. {
  2208.     if (p->n > 1)
  2209.     {
  2210.         // disconnect self
  2211.         p->n--;
  2212.         p = new srep;
  2213.     }
  2214.     else                                        // free old string
  2215.         delete[]p->s;
  2216.  
  2217.     p->s = new
  2218.           char[strlen(s) + 1];
  2219.     strcpy(p->s, s);
  2220.     return *this;
  2221. }
  2222.  
  2223.  
  2224. TString& TString::operator=(const TString& x)
  2225. {
  2226.     x.p->n++;                                    // protect against 'st = st'
  2227.     if (--p->n == 0)
  2228.     {
  2229.         delete[]p - s;
  2230.         delete p;
  2231.     }
  2232.     p = x.p;
  2233.     return *this;
  2234. }
  2235.  
  2236.  
  2237.  
  2238.  
  2239. ostream& operator<<(ostream& s,
  2240.                     const TString& x)
  2241. {
  2242.     return s << x.p->s << " [" << x.p->n << "]\n";
  2243. }
  2244.  
  2245.  
  2246. istream& operator>>(istream& s,
  2247.                     TString& x)
  2248. {
  2249.     char buf[256];
  2250.     s.get(buf, 256);
  2251.     char c;
  2252.     if (s.get(c) && c != '\n')
  2253.     {
  2254.         // buffer overflow, line longer than buffer
  2255.     }
  2256.  
  2257.     x = buf;
  2258.     cout << "echo: " << x << '\n';
  2259.     return s;
  2260. }
  2261.  
  2262.  
  2263. void error(const char* p)
  2264. {
  2265.     cerr << p << '\n';
  2266.     exit(1);
  2267. }
  2268.  
  2269.  
  2270.  
  2271.  
  2272. char& TString::operator[](int i)
  2273. {
  2274.     if (i < 0 || strlen(p->s) < i)
  2275.         error("index out of range");
  2276.     return p->s[i];
  2277. }
  2278.  
  2279.  
  2280.  
  2281.  
  2282. int main()                                        // example of usage
  2283. {
  2284.     TString x[100];
  2285.  
  2286.     cout << "here we go!\n";
  2287.  
  2288.     for (int n = 0; cin > x[n]; n++)
  2289.     {
  2290.         if (n == 100)
  2291.         {
  2292.             error("too many strings");
  2293.             return 99;
  2294.         }
  2295.  
  2296.         TString y;
  2297.         cout << (y = x[n]);
  2298.         if (y == "done")
  2299.             break;
  2300.     }
  2301.  
  2302.     cout << "here we go back again!\n";
  2303.     for (int i = n - 1; 0 <= i; i--)
  2304.         cout << x[i];
  2305.  
  2306.     return 0;
  2307. }
  2308.  
  2309.  
  2310.  
  2311.  
  2312. // CASTING OF CLASS
  2313. class TBase { ... } b;
  2314. class Tdpriv : private TBase { ... } dv;
  2315. class Tdpub  : public  TBase { ... } db;
  2316. foo(TBase b) { ... }
  2317.  
  2318. foo(b);            // legal
  2319. foo(db);        // legal
  2320. foo(dv);        // NOT legal!!
  2321. foo((TBase)dv);    // legal
  2322.  
  2323.  
  2324. // ACCESS CONTROL ADJUSTMENT
  2325. class TBase
  2326. {
  2327. public:
  2328.     virtual void func(void)
  2329.     {
  2330.     }
  2331.     ;
  2332. };
  2333.  
  2334.  
  2335. class derived1 : private TBase
  2336. {
  2337. public:
  2338.     TBase::func;
  2339. };
  2340.  
  2341.  
  2342.  
  2343.  
  2344.  
  2345. class derived2 : private derived1
  2346. {
  2347. public:
  2348.     void func(void)
  2349.     {
  2350.     }
  2351.     ;
  2352. };
  2353.  
  2354.  
  2355. main()
  2356. {
  2357.     derived2 * foo = new derived2;
  2358.     return 0;
  2359. }
  2360.  
  2361.  
  2362.  
  2363.  
  2364. // MORE ESOTERIC TRICKS
  2365.  
  2366.  
  2367. // PASSING VARIABLE ARGUMENTS TO CONSTRUCTOR
  2368. #include <stdarg.h>
  2369.  
  2370. class TBase {  ... TBase(int); Init(va_list); ... };
  2371.  
  2372. class TDerived : public TBase { ... TDerived(int, ...); ... };
  2373.  
  2374. TDerived::TDerived(int i,
  2375.                    ...) :
  2376.     TBase(i)
  2377. {
  2378.     va_list ap;
  2379.     va_start(ap, i);
  2380.     Init(ap);
  2381.     va_end(ap);
  2382. }
  2383.  
  2384.  
  2385.  
  2386.  
  2387.  
  2388.         
  2389.  
  2390.  
  2391.         
  2392.  
  2393.     
  2394.